<?php
namespace App\Support;

use App\Models\Order;
use App\Models\Shop;
use App\Models\WxTpl;

class Printer
{
    protected $user = 'yufan@qudingshui.com';
    protected $uKey = 'EksVrXQxWutqVb73';

    protected $base_url = 'api.feieyun.cn';//接口IP或域名
    protected $port = '80';//接口IP端口
    protected $path = '/Api/Open/';//接口路径
    protected $sTime = '';//公共参数，请求时间
    protected $sign = ''; //公共参数，请求公钥
    protected $url = '';
    protected $str_len = 32;

    public function __construct()
    {
        $this->sTime = time();
        $this->sign = sha1($this->user.$this->uKey.$this->sTime);
        $this->url = $this->base_url.':'.$this->port.$this->path;
    }

    // 添加打印机
    public function addPrinter($snlist)
    {
        $data = [
            'user'=>$this->user,
            'stime'=>$this->sTime,
            'sig'=>$this->sign,
            'apiname'=>'Open_printerAddlist',
            'printerContent'=>$snlist
        ];
        $res = curlPost($this->url, $data);
        $res = json_decode($res,true);
        // 判断打印机是否添加成功
        if($res && $res['data']['no']){
            return false;
        } else{
            return true;
        }
    }

    // 打印订单
    public function orderPrint($printer_sn,$content,$times = 1)
    {
        $data = [
            'user'=>$this->user,
            'stime'=>$this->sTime,
            'sig'=>$this->sign,
            'apiname'=>'Open_printMsg',
            'sn'=>$printer_sn,
            'content'=>$content,
            'times'=>$times//打印次数
        ];
        $res = curlPost($this->url, $data);
        $res = json_decode($res,true);
        if($res && $res['ret'] != 0){
            return false;
        } else{
            return true;
        }
    }

    // 查询订单是否打印成功
    public function queryOrderState($index){
        $data = [
            'user'=> $this->user,
            'stime'=> $this->sTime,
            'sig'=> $this->sign,
            'apiname'=>'Open_queryOrderState',
            'orderid'=>$index
        ];

        $res = curlPost($this->url, $data);
        $res = json_decode($res,true);
        if($res && $res['ret'] != 0){
            return false;
        } else{
            return true;
        }
    }

    // 查询打印机状态
    public function queryPrinterStatus($printer_sn){
        $data = [
            'user'=> $this->user,
            'stime'=> $this->sTime,
            'sig'=> $this->sign,
            'apiname'=>'Open_queryPrinterStatus',
            'sn'=>$printer_sn
        ];

        $res = curlPost($this->url, $data);
        $resData = json_decode($res,true);
        $printerStatus = 0;
        if($resData && $resData['ret'] == 0) {
            $printerStatus = 2; // 打印机存在
            if(strpos($resData['data'],'在线') !== false){
                if(strpos($resData['data'],'不正常') === false) {
                    $printerStatus = 1;
                }
            }
        }
        return $printerStatus;
    }

    // 删除打印机
    public function delPrinter($serial_number)
    {
        $data = [
            'user'=> $this->user,
            'stime'=> $this->sTime,
            'sig'=> $this->sign,
            'apiname'=>'Open_printerDelList',
            'snlist'=> $serial_number
        ];
        $res = curlPost($this->url, $data);
        $res = json_decode($res,true);
        // 判断打印机是否删除成功
        if($res && isset($res['ret'])){
            echo false;
        } else{
            echo true;
        }
    }

    /**
     *
    <BR> ：换行符
    <CUT> ：切刀指令(主动切纸,仅限切刀打印机使用才有效果)
    <LOGO> ：打印LOGO指令(前提是预先在机器内置LOGO图片)
    <PLUGIN> ：钱箱或者外置音响指令
    <CB></CB>：居中放大
    <B></B>：放大一倍
    <C></C>：居中
    <L></L>：字体变高一倍
    <W></W>：字体变宽一倍
    <QR></QR>：二维码
    <RIGHT></RIGHT>：右对齐
    <BOLD></BOLD>：字体加粗
     *
     *
     一行32个‘-’   名称长度：14，空格 1  单价 6 空格 1 数量3 空格 1 金额 6
     *
     */
    // 打印排版
    public function typeSetting($orderInfo)
    {
        $where['id'] = ['>', 0];
        $where['is_add'] = ['=', 1];
        $where['status'] = ['=' ,1];
        $where['shop_id'] = $orderInfo['shop_id'];
        $printer = (new \App\Models\Printer())->_getOne($where);
        if($printer) {
            $order = new Order();
            $orderInfo = $order->getOrderInfoById($orderInfo['id']);
            $serial_number = $printer->serial_number;
            // 查询打印机状态
//            $printerStatus = $this->queryPrinterStatus($serial_number);
            try{
                if($orderInfo) { // && $printerStatus == 1
                    $content = '';

                    // 查询店铺信息
                    $shopInfo = (new Shop())->_getOneById($orderInfo['shop_id']);
                    $shop_name = $shopInfo ? $shopInfo['shop_name'] : '';
                    $content .= '<CB>'.$shop_name.'</CB><BR>';
                    $content .= '<C>'.$this->bar_code($orderInfo['order_sn']).'</C><BR>';
                    $content .= '下单时间：'.$orderInfo['created_at'].'<BR>';

                    $content .= str_repeat('-',$this->str_len).'<BR>';
                    $content .= '<BOLD>收货地址：'.$orderInfo['buyer_address'].'</BOLD><BR>';
                    $content .= str_repeat('-',$this->str_len).'<BR>';

                    $content .= '名称           单价  数量 金额<BR>';
                    $content .= '<BR>';
                    $orderGoods = $orderInfo['order_goods'];

                    // 商品相关
                    foreach($orderGoods as $item){
                        $front = $item['goods_name'];
                        $frontFlag = false; // 是否换行
                        $chineseLen = $this->chineseNum($front);
                        $alpha = mb_strlen(trim($item['goods_name'])) - $chineseLen; // 英文与数字个数
                        $frontLen = $alpha + $chineseLen * 2; // 最终长度
                        // 计算商品名称长度
                        if($frontLen > 14) {
                            $front .= ' <BR>';
                            $frontFlag = true;
                        } else {
                            if(15 - $frontLen > 0) {
                                $space = str_repeat(' ', 15 - $frontLen);
                                $front .= $space;
                            }

                        }
                        $content .= $front;
                        // 计算单价、数量、金额长度
                        $back = '';
                        $price = $item['goods_price'];
                        $num = $item['goods_num'];
                        $amount = bcmul($item['goods_price'],$item['goods_num'],2);

                        $priceLen = mb_strlen($price);
                        if($priceLen < 6) {
                            $price .= str_repeat(' ', 6 - $priceLen);
                        }
                        $back .= $price.' ';

                        $numLen = mb_strlen($num);
                        if($numLen < 3) {
                            $num .= str_repeat(' ', 3 - $numLen);
                        }
                        $back .= $num.' ';

                        $amountLen = mb_strlen($amount);
                        if($amountLen < 6) {
                            $amount .= str_repeat(' ', 6 - $amountLen);
                        }
                        $back .= $amount;

                        if($frontFlag) {
                            $content .= str_repeat(' ',$this->str_len - mb_strlen($back)).$back.'<BR>';
                        } else {
                            if(mb_strlen($back) > 17) {
                                $content .= '<BR>';
                                $content .= str_repeat(' ',$this->str_len - mb_strlen($back)).$back.'<BR>';
                            } else {
                                $content .= $back.'<BR>';
                            }
                        }
                    }

                    // 合计
                    $sum = $orderInfo['order_amount'];
                    $sumSpace = $this->str_len - 6 - mb_strlen($sum);
                    $content .= str_repeat(' ',$sumSpace).'合计：'.$sum.'<BR>';

                    // 分割线
                    $content .= str_repeat('-',$this->str_len).'<BR>';
                    $content .= '客户名称：'.$orderInfo['buyer_name'].'<BR>';
                    $content .= '联系方式：'.$orderInfo['mobile'].'<BR>';
                    $content .= '余票：'.$orderInfo['member']['total_waterbill_num'].' 总水桶：'.$orderInfo['member']['total_bucket_num'].' 借桶：'.$orderInfo['member']['borrow_bucket_num'].'<BR>';
                    $content .= str_repeat('-',$this->str_len).'<BR>';
                    // 应收订单款
                    if($orderInfo['type'] == 1){
                        $content .= '<BOLD>应收订单款：'.$orderInfo['order_amount'].'</BOLD><BR>';
                    }
                    // 应收水票款
                    if(count($orderInfo['bill_order']) && $orderInfo['bill_order']['money']) {
                        $content .= '<BOLD>应收水票款：'.$orderInfo['bill_order']['money'].'</BOLD><BR>';
                    }
                    // 赠送信息
                    if(count($orderInfo['bill_order']) && isset($orderInfo['bill_order']['description'])) {
                        $description = $orderInfo['bill_order']['description'];
                        if(count($description)){
                            $content .= str_repeat('-',$this->str_len).'<BR>';// 分割线
                            $content .= '赠送信息：'.'<BR>';
                            foreach($description as $item) {
                                $content .= $item.'<BR>';
                            }
                            $content .= str_repeat('-',$this->str_len).'<BR>';// 分割线
                        }

                    }
                    if($orderInfo['description']){
                        $content .= '留言：'.$orderInfo['description'].'<BR>';
                    }
                    if($content) {
                        $this->orderPrint($serial_number,$content);
                    }
                    $wxTpl = new WxTpl();
                    $wxTpl->preSendOrderMsgBySys($orderInfo);
                    return true;
                } else {
                    return false;
                }
            }catch(\Exception $e){
                return false;
            }
        }
    }

    // 计算汉字个数
    public function chineseNum($str)
    {
        $encode = 'UTF-8';
        $str_num = mb_strlen($str, $encode);
        $j = 0;
        for($i=0; $i < $str_num; $i++)
        {
            if(ord(mb_substr($str, $i, 1, $encode))> 0xa0)
            {
                $j++;
            }
        }
        return $j;
    }

    // 一维条形码
    public function bar_code($strnum)
    {
        $codeB = array("\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39");//匹配字符集B
        $codeC = array("\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F","\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2A","\x2B","\x2C","\x2D","\x2E","\x2F","\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3A","\x3B","\x3C","\x3D","\x3E","\x3F","\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4A","\x4B","\x4C","\x4D","\x4E","\x4F","\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5A","\x5B","\x5C","\x5D","\x5E","\x5F","\x60","\x61","\x62","\x63");//匹配字符集C
        $length = strlen($strnum);
        $b=array();
        $b[0] = "\x1b";
        $b[1] = "\x64";
        $b[2] = "\x02";
        $b[3] = "\x1d";
        $b[4] = "\x48";
        $b[5] = "\x32";
        $b[6] = "\x1d";
        $b[7] = "\x68";
        $b[8] = "\x50";
        $b[9] = "\x1d";
        $b[10] = "\x77";
        $b[11] = "\x02";
        $b[12] = "\x1d";
        $b[13] = "\x6b";
        $b[14] = "\x49";
        $b[15]  = chr($length + 2);
        $b[16] = "\x7b";
        $b[17] = "\x42";
        if($length > 14){//大于14个字符的进来这个区间
            $b[17] = "\x43";
            $j = 0;
            $key = 18;
            $ss = $length/2;//初始化数组长度
            if($length%2 == 1){//判断条形码为单数
                $ss = $ss-0.5;
            }
            for ($i = 0; $i < $ss; $i++){
                $temp = substr($strnum,$j,2);
                $iindex = intval($temp);
                $j = $j+2;
                if($iindex == 0){
                    if($b[$key + $i-1] == '0' && $b[$key + $i-2] == '0'){//判断前面的为字符集B,此时不需要转换字符集
                        $b[$key + $i] = $codeB[0];
                        $b[$key + $i + 1] = $codeB[0];
                        $key += 1;
                    }else{
                        if($b[$key + $i-1] == 'C' && $b[$key + $i-2] == '{'){//判断条形码开头前两位数都为0时转换字符集B
                            $b[$key + $i - 2] = "\x7b";
                            $b[$key + $i - 1] = "\x42";
                            $b[$key + $i] = $codeB[0];
                            $b[$key + $i + 1] = $codeB[0];
                            $key += 1;
                        }else{
                            $b[$key + $i] = "\x7b";
                            $b[$key + $i + 1] = "\x42";
                            $b[$key + $i + 2] = $codeB[0];
                            $b[$key + $i + 3] = $codeB[0];
                            $key += 3;
                        }
                    }
                }else{
                    if($b[$key + $i-1] == '0' && $b[$key + $i-2] == '0' && $iindex != '89'){//判断前面的为字符集B,此时要转换字符集C
                        $b[$key + $i] = "\x7b";
                        $b[$key + $i + 1] = "\x43";
                        $b[$key + $i + 2] = $codeC[$iindex];
                        $key += 2;
                    }else{
                        $b[$key + $i] = $codeC[$iindex];
                    }
                }
            }
            @$lastkey = end(array_keys($b));//取得数组的最后一个元素的键
            if($length % 2 > 0){
                $lastnum = substr($strnum,-1);//取得字符串的最后一个数字
                if($b[$lastkey] == '0' && $b[$lastkey-1] == '0'){//判断前面的为字符集B,此时不需要转换字符集
                    $b[$lastkey + 1] = $codeB[$lastnum];
                }else{
                    $b[$lastkey + 1] = "\x7b";
                    $b[$lastkey + 2] = "\x42";
                    $b[$lastkey + 3] = $codeB[$lastnum];
                }
            }
        }else{//1-14位数字的条形码进来这个区间
            for ($i = 0; $i < $length; $i++){
                $temp = substr($strnum,$i,1);
                $iindex = intval($temp);
                $b[18 + $i] = $codeB[$iindex];
            }
        }
        @$b[15] = chr(end(array_keys($b)) - 15);//得出条形码长度
        $str = implode("",$b);
        return $str;
    }

}